package lvbu.wang.lvbuoperator.utils;

import com.qing.library.utils.StringUtil;

import java.util.HashMap;

import lvbu.wang.lvbuoperator.xmode.CRC16;


/**
 * Created by DaiQing.Zha on 2017/4/28 0028.
 * 命令处理相关的工具类
 * 包如何括拼接要发送的命令
 * 接收到电机返回的应答后后如何进行拆分
 */
public class CommandUtils {

    public final static String FIXED_COMMAND_HEAD = "7E";      //固定命令头
    public final static String FLAG_SET = "0B";                //设置标志
    public final static String FLAG_GET = "0C";               //查询标志
    public final static int CRC_CHECK_CODE_LENGTH = 2;    //CRC校验码长度

    /**
     * 获取一条完整的设置命令
     * @param commandHead
     * @param value
     * @return
     */
    public static String getSetCommand(String commandHead,String value){
        String result;
        String command = FLAG_SET + commandHead + value;    //命令
        int commandLength = command.length() / 2;   //命令长度
        String surplusLength = FormatUtil.intToHex(commandLength + CRC_CHECK_CODE_LENGTH);  //剩余长度
        byte[] crcCheckCode = getCrcCheckCode(StringUtil.hexStringToBytes(surplusLength + command));    //crc校验码
        result = FIXED_COMMAND_HEAD + surplusLength + command + StringUtil.bytesToHexString(crcCheckCode);   //一条完整的发送命令
        return result;
    }

    /**
     * 获取一条完整的查询命令
     * @param commandHeads
     * @return
     */
    public static String getInquireCommand(String[] commandHeads){
        String result;
        String commandHeadStr = "";
        for (int i = 0; i < commandHeads.length; i ++){
            commandHeadStr += commandHeads[i];
        }
        String dataField = FLAG_GET + commandHeadStr;
        int dataFieldLength = dataField.length() / 2;
        String surplusLength = FormatUtil.intToHex(dataFieldLength + CRC_CHECK_CODE_LENGTH);
        byte[] crcCheckCode = getCrcCheckCode(StringUtil.hexStringToBytes(surplusLength + dataField));
        result = FIXED_COMMAND_HEAD + surplusLength + dataField + StringUtil.bytesToHexString(crcCheckCode);
        return result;
    }

    /**
     * 获取CRC校验码
     * @param value
     * @return
     */
    private static byte[] getCrcCheckCode(byte[] value){
        byte[] checkCode = new byte[2]; //crc校验码
        CRC16 crc16 = new CRC16();
        long longCheckCode = crc16.calcCRC(value);
        for (int i = 0; i < crc16.getCRCLength(); i++) {
            checkCode[crc16.getCRCLength() - i - 1] = (byte) ((longCheckCode >> (8 * i)) & 0xFF);
        }
        return checkCode;
    }

    /**
     * 获取查询指令电机应答结果的键值对
     * @param answerContent
     * @return
     */
    public static HashMap getInquireMap(String answerContent){
        HashMap map = new HashMap();
        int position = 8;
        String key = "";
        while (position < answerContent.length() - CommandUtils.CRC_CHECK_CODE_LENGTH * 2){
            String tempKey = StringHelper.subString(answerContent,position,position + 2);
            key = key + tempKey;
            position = position + 2;
            int answerResultLength = Integer.parseInt(StringHelper.subString(answerContent,position,position + 2),16);
            map.put(tempKey,StringHelper.subString(answerContent,position + 2,position + answerResultLength * 2 + 2));
            position = position + 2 + answerResultLength * 2;
        }
        return map;
    }

    /**
     * 根据应答结果获取命令的key
     * @param commandAnswer
     * @return
     */
    public static String getCommandKey(String commandAnswer){
        String key = "";
        String flag = StringHelper.subString(commandAnswer,4,6).toUpperCase();
        int orderRealLength = Integer.parseInt(StringHelper.subString(commandAnswer,2,4),16);
        commandAnswer = StringHelper.subString(commandAnswer,0,(orderRealLength + 2) * 2);
        if (CommandUtils.FLAG_SET.equals(flag)){
            key = flag + StringHelper.subString(commandAnswer,8,10);
        }else if (CommandUtils.FLAG_GET.equals(flag)){
            int position = 8;
            while (position < commandAnswer.length() - CommandUtils.CRC_CHECK_CODE_LENGTH * 2){
                key = key + StringHelper.subString(commandAnswer,position,position + 2);
                position = position + 2;
                int answerResultLength = Integer.parseInt(StringHelper.subString(commandAnswer,position,position + 2),16);
                position = position + 2 + answerResultLength * 2;
            }
            key = flag + key;
        }
        key = key.toUpperCase();
        return key;
    }
}
